from platform import version
import xml.etree.ElementTree as ET
import subprocess
import sys
import re


class CommentedTreeBuilder(ET.TreeBuilder):
    def comment(self, data):
        self.start(ET.Comment, {})
        self.data(data)
        self.end(ET.Comment)


def register_all_namespaces(filename):
    namespaces = dict([node for _, node in ET.iterparse(filename, events=["start-ns"])])
    for ns in namespaces:
        ET.register_namespace(ns, namespaces[ns])


def change_one_xml(
    path_result,
    install_project,
    xml_path,
    group_dw,
    artifact_dw,
    force,
    update_content,
    source_keep=False,
):
    # 打开xml文档
    parser = ET.XMLParser(target=CommentedTreeBuilder())
    tree = ET.parse(xml_path, parser=parser)
    root = tree.getroot()
    location_name = root.tag[: root.tag.index("}") + 1]
    locationUrl = location_name[1:-1]
    flag = False
    for node in root.findall(".//" + location_name + "dependency"):
        groupIdNode = node.find("." + location_name + "groupId")
        artifactNode = node.find("." + location_name + "artifactId")
        if artifactNode.text == artifact_dw and groupIdNode.text == group_dw:
            versionNode = node.find("" + location_name + "version")
            if (versionNode is not None) and ("${project}" != versionNode.text):
                versionNode.text = judge_version(
                    source_keep, force, versionNode.text, update_content
                )
                update_content = versionNode.text
                flag = True
    # print(node.tag.split('}')[-1])
    # 查找修改路劲
    #    sub1 = root.find(xml_dw)
    # 修改标签内容
    #    sub1.text = update_content
    # 保存修改
    if flag is True:
        print(1)
        # register_all_namespaces(None)
        tree.write(
            xml_path,
            xml_declaration=True,
            encoding="utf-8",
            method="xml",
            default_namespace=locationUrl,
        )
    else:
        update_content = change_self_version(
            path_result, install_project, xml_path, force, update_content
        )
    return update_content


def judge_version(keep_source, force, old_text, new_text):
    if keep_source is True:
        return old_text
    source_old = old_text
    if re.compile("^\\$\\{.*\\}$").match(old_text) or re.compile("^\\$\\{.*\\}$").match(
        source_old
    ):
        return source_old
    if force is None or force is False:
        old_text = old_text.replace("\n", "")
        old_text = old_text.replace("$", "\$")
        print("old...." + old_text)
        result = subprocess.getoutput(
            "sh {}/version.sh {} | sed -n '$p' ".format(sys.path[0], old_text)
        )
        print(result + "..........")
        return result
    return (old_text.split("1.2.5")[0].strip() + new_text).strip()


def change_self_version(
    path_result,
    install_project,
    xml_path,
    force,
    update_content,
    write=True,
    source_keep=False,
):
    if "yujingshan" in xml_path:
        # do not update yujingshan project
        return update_content
    # 打开xml文档
    parser = ET.XMLParser(target=CommentedTreeBuilder())
    tree = ET.parse(xml_path, parser=parser)
    # tree = ET.parse(xml_path)
    root = tree.getroot()
    location_name = root.tag[: root.tag.index("}") + 1]
    locationUrl = location_name[1:-1]
    versionNode = root.find("." + location_name + "version")
    returnValue = version
    if versionNode is None:
        # update parent version
        parentNode = root.find("." + location_name + "parent")
        parentVersionNode = parentNode.find("." + location_name + "version")
        groupIdNode = parentNode.find("." + location_name + "groupId")
        artifactIdNode = parentNode.find("." + location_name + "artifactId")
        item = "{}->{}".format(artifactIdNode.text, groupIdNode.text)
        if item in install_project:
            parentVersionNode.text = install_project[item]
        else:
            # parentVersionNode.text = judge_version(
            #     source_keep, force, parentVersionNode.text, update_content
            # )
            parentVersionNode.text = change_self_version(
                path_result,
                install_project,
                path_result[item],
                force,
                update_content,
                write,
                source_keep,
            )
            install_project[item] = parentVersionNode.text
        returnValue = parentVersionNode.text
    else:
        groupIdSelfNode = root.find("." + location_name + "groupId")
        artifactIdSelfNode = root.find("." + location_name + "artifactId")
        if groupIdSelfNode is None:
            parentNode = root.find("." + location_name + "parent")
            parentVersionNode = parentNode.find("." + location_name + "version")
            groupIdSelfNode = parentNode.find("." + location_name + "groupId")
        itemSelf = "{}->{}".format(groupIdSelfNode.text, artifactIdSelfNode.text)
        if itemSelf in install_project:
            return install_project[itemSelf]
        versionNode.text = judge_version(
            source_keep, force, versionNode.text, update_content
        )
        install_project[itemSelf] = versionNode.text
        returnValue = versionNode.text
    # 保存修改
    # register_all_namespaces(None)
    if write is True:
        tree.write(
            xml_path,
            xml_declaration=True,
            encoding="utf-8",
            method="xml",
            default_namespace=locationUrl,
        )
    return returnValue
